-- tablecmd.lua 处理其他service的调用,主要是
-- 桌子的命令，就是 start， reload， delete ,核心是去调用 tablelogic 的函数
local filename = "tablecmd.lua"

local skynet = require "skynet"

local filelog = require "filelog"
local timetool = require "timetool"
local tabletool = require "tabletool"
local timer = require "timer"

require "mjexenum"

local CMD = {}
local service = nil
local tablelogic = nil

function CMD.init(caller)
	service = caller
	tablelogic = service:get_logicbyname("tablelogic")
end

--
-- 处理cmd类型消息
--
function  CMD.cmd(subcmd,...)
    local f = CMD[subcmd]
    if f == nil then
        return
    end

    return f(...)
end

--------------------------------

--
-- 杀死服务
--
function CMD.kill_service(...)
	service:exit_service()
end

--
-- 从 nodecmd的 createtable()里面调用
--
function CMD.start(conf, attachconf)
	tablelogic.init_data(service.table_data, conf, attachconf)
	return true
end

--
-- 重新加载配置
--
function CMD.reload(conf)
	local table_data = service.table_data

	---判断桌子是否在游戏中,如果是在游戏中，将配置文件缓存
	if not tablelogic.is_gameend(table_data) then
		table_data.backofconf = tabletool.deepcopy(conf)
		return
	end
	for key, value in pairs(conf) do
		table_data.conf[key] = value 
	end
end

--
--删除桌子
--
function CMD.delete(delete_reason)
    filelog.print("-----------------CMD.delete")

	local table_data = service.table_data
	table_data.isdeleting = true
	--踢出座位上的玩家
	tablelogic.leavetableallplayer(table_data, EStandupReason.STANDUP_REASON_DELETE_TABLE)
	local waits = tabletool.deepcopy(table_data.waits) or { }
	for rid, waitinfo in pairs(waits) do
		tablelogic.passive_leavetable(table_data, rid,waitinfo.playerinfo.diamond)
	end
	
    local table_index = table_data.index	

     --保存桌子记录
    if table_data.game_records ~= nil then
        table_data.game_records.delete_time = timetool.get_time()
        if delete_reason ~= nil then
            table_data.game_records.delete_reason = delete_reason
        end
        tablelogic.save_table_final_records(table_data)
    end

	--删除桌子前清除桌子的状态
	tablelogic.clear(table_data)

    --通知router删除table
	skynet.send(".router", "lua", "delete_table", nil,table_index)
	
    --关闭服务
	service:exit_service()
end

--
-- 玩家钻石改变时的通知，来自gate
--
function CMD.rid_change_diamond(rid, begindiamond, value, enddiamond)
	print(filename .. "line98", rid, begindiamond, value, enddiamond)

    if enddiamond ~= begindiamond + value then
        return false
    end

    local tableobj = service.table_data
    for _,seat in pairs(tableobj.seats) do
        if seat.rid == rid then
            if seat.playerinfo.diamond ~= begindiamond then
                return false
            end
            seat.playerinfo.diamond = enddiamond
            if tableobj.curr_seats_money and tableobj.curr_seats_money[seat.rid] then
                tableobj.curr_seats_money[seat.rid].diamond = tableobj.curr_seats_money[seat.rid].diamond + value
            end
            --通知客户端
            local noticemsg = {
                money_change_list = { },
            }
            table.insert(noticemsg.money_change_list,{rid = rid,money_type = EMoneyType.DIAMOND,change_value = value,final_value = enddiamond})
            tablelogic.sendmsg_to_alltableplayer(tableobj,"moneychangeN",noticemsg)
            break
        end
    end
   
   return true 
end

--
-- 玩家钻石改变时的通知，来自gate
--
function CMD.rid_change_coin(rid, begincoin, value, endcoin)
	print(filename .. "line98", rid, begincoin, value, endcoin)

    if endcoin ~= begincoin + value then
        return false
    end

    local tableobj = service.table_data
    for _,seat in pairs(tableobj.seats) do
        if seat.rid == rid then
            if seat.playerinfo.coin ~= begincoin then
                return false
            end
            seat.playerinfo.coin = endcoin
            if tableobj.curr_seats_money and tableobj.curr_seats_money[seat.rid] then
                tableobj.curr_seats_money[seat.rid].coin = tableobj.curr_seats_money[seat.rid].coin + value
            end
            --通知客户端
            local noticemsg = {
                money_change_list = { },
            }
            table.insert(noticemsg.money_change_list,{rid = rid,money_type = EMoneyType.COIN,change_value = value,final_value = endcoin})
            tablelogic.sendmsg_to_alltableplayer(tableobj,"moneychangeN",noticemsg)
            break
        end
    end
   
   return true 
end

--
-- 获得桌子数据
--
function CMD.get_table_data()
    local tableobj = service.table_data
    local data = {
        table_index	= tableobj.index,
		table_code	= tableobj.code,
		conf	= tableobj.conf,
		cur_player	= tableobj.sitdown_player_num,
		create_time	= tableobj.create_time,
        create_rid = tableobj.create_rid,
   }
   return data
end

--
-- 获得所有rids
--
function CMD.get_table_allrid()
    local rids = { }
    local tableobj = service.table_data

    for _,seat in pairs(tableobj.seats) do
        if seat.state == EMJSeatState.SEAT_STATE_NO_PLAYER 
        or seat.rid <= 0 or seat.has_leave then
        
        else
            table.insert(rids,seat.rid)
        end
    end
    for _,w in pairs(tableobj.waits) do
        table.insert(rids,w.rid)
    end
    
   return rids
end

--
-- 获得公开桌列表
-- 正常不会收到，容错处理
--
function CMD.getpubtablelist(rid, roledata)
    return skynet.call(".router","lua","getpubtablelist",nil,rid,roledata)
end

--
-- 获得桌子状态:人数和状态
--
function CMD.gettablestate()
    local tableobj = service.table_data
    local sitdown_num = 0
    local watch_num = tableobj.cur_watch_playernum or 0
    local max_player_num = tableobj.conf.max_player_num or 0
    local delete_timer = tableobj.delete_table_timer_id or -1
    local is_deleteing = false
    if delete_timer > 0 or tableobj.isdeleting then
        is_deleteing = true
    end

    --获得坐下人数
    for _,seat in pairs(tableobj.seats) do
        if seat.state == EMJSeatState.SEAT_STATE_NO_PLAYER 
        or seat.rid <= 0 or seat.has_leave then
            
        else
            sitdown_num = sitdown_num + 1
        end
    end
    
    local msg = {
        cur_player_num = sitdown_num + watch_num,       --当前桌内人数
        watch_player_num = watch_num,                   --当前旁观人数
        max_player_num = max_player_num,                --桌子支持最大人数
        table_state = tableobj.state,                   --桌子状态
        last_heart_time = tableobj.last_heart_time,     --上次心跳时间
        is_ingame = tableobj.is_ingame,                 --是否游戏中
        is_deleteing = is_deleteing,                    --是否删除中
        table_type = tableobj.table_type,               --桌子类型
        match_type = tableobj.match_type,               --匹配场类型
    }
    return msg
end

--
-- 定时删除桌子
--
function CMD.delete_table_by_timer()
    local tableobj = service.table_data
    tableobj.delete_table_timer_id = tableobj.delete_table_timer_id or -1
    if tableobj.isdeleting or tableobj.delete_table_timer_id > 0 then
        return
    end

    tableobj.delete_table_timer_id = timer.settimer(5,"delete_table")
    if tableobj.delete_table_timer_id < 0 then  --设置定时器失败,则直接删除
        CMD.delete(EMJTableDeleteReason.DELETE_REASON_SYSTEM_ERROR)
    end
end

--
-- 初始化robot
--
function CMD.init_robot(seat_index)
    timer.settimer(100, "do_robot_tuoguan",{index = seat_index})
end

--
-- 设置桌子结束标记,标记后在一局结束后桌子将被删除
--
function CMD.set_tableend_flag()
    service.table_data.tableend_flag = true

    --如果桌子还未开始游戏直接解散
    if service.table_data.state == EMJTableState.TABLE_STATE_WAIT_PLAYER_SITDOWN
    or service.table_data.state == EMJTableState.TABLE_STATE_WAIT_ALL_READY then
        CMD.delete(EMJTableDeleteReason.DELETE_REASON_SYSTEM_REQUIRE)
    end
end

--
--获取桌子数据
--rid为空，表示是调度服务拉取数据
--
function CMD.get_tableinfo(rid)
    local tableobj = service.table_data
    local table_info = { }

    if rid then
        table_info.other_info = {}
        table_info.self_info = {}
        for _,seat in pairs(tableobj.seats) do
            local item = {
                rid = seat.rid,
                level = seat.playerinfo.level or 0,
                que_cardcolor = seat.que_cardcolor,
                cards = tabletool.deepcopy(seat.cards),
                di_cards = tabletool.deepcopy(seat.di_cards),
                out_cards = tabletool.deepcopy(seat.out_cards),
                chi_cards = tabletool.deepcopy(seat.chi_cards),
            }
            if rid == seat.rid then
                table_info.self_info = item
            else
                table.insert(table_info.other_info, item)
            end
        end
    else
        table_info.robot_rids = {}  --机器人rid列表
        for _,seat in pairs(tableobj.seats) do
            if seat.playerinfo.level == 99 then
                table.insert(table_info.robot_rids, seat.rid)
            end
        end

        local is_ingame = not tablelogic.is_onegameend(tableobj)
        table_info.table_index = tableobj.index         --桌子索引
        table_info.state = tableobj.state               --桌子状态
        table_info.table_type = tableobj.table_type     --桌子类型
        table_info.match_type = tableobj.match_type     --匹配场类型
        table_info.is_ingame = is_ingame                --是否游戏中
        table_info.is_public = tableobj.conf.is_public  --是否公开桌
        table_info.cur_player = tableobj.sitdown_player_num --当前玩家数
        table_info.max_player = tableobj.conf.max_player_num--最大玩家数
        table_info.base_score = tableobj.conf.score_diamond --桌子底注
        table_info.enter_score = tableobj.conf.enter_diamond--桌子入场底注
    end

    return table_info
end

return CMD